package com.intelligentpension.kotlinbluetoothprint.printutils

import java.io.ByteArrayOutputStream

/**
 * 版权：点赞 版权所有
 * author :赵航
 * @e-mail: zhaohangcn@gmail.com
 * time：2022/4/14
 * describe ：
 */
class PrinterWriter(width: Int, height: Int) {
    var bos: ByteArrayOutputStream = ByteArrayOutputStream()


    val CHARSET = "gb2312"
    val ESC: Byte = 27 //换码
    val FS: Byte = 28 //文本分隔符
    val GS: Byte = 29 //组分隔符
    val DLE: Byte = 16 //数据连接换码
    val EOT: Byte = 4 //传输结束
    val ENQ: Byte = 5 //询问字符
    val SP: Byte = 32 //空格
    val HT: Byte = 9 //横向列表
    val LF: Byte = 10 //打印并换行（水平定位）
    val CR: Byte = 13 //归位键
    val FF: Byte = 12 //走纸控制（打印并回到标准模式（在页模式下） ）
    val CAN: Byte = 24 //作废（页模式下取消打印数据 ）


    /**
     *  初始化数据
     */
    init {
        write(initPrinter())
    }

    /**
     * 渲染
     */
    fun write(data: ByteArray) {
        bos.write(data)
    }

    /**
     * 设置居中
     */
    fun setAlignCenter() {
        write(alignCenter())
    }

    /**
     * 获取  预打印数据并重置流
     */
    fun getDataAndReset(): ByteArray {
        bos.flush()
        var data = bos.toByteArray()
        bos.reset()
        return data
    }

    /**
     * 设置左对齐
     */
    fun setAlignLeft() {
        write(alignLeft())
    }

    /**
     * 写入一条线
     */
    fun printLine() {
        var length = getLineWidth()
        var line: String = ""
        while (length > 0) {
            line += "- "
            length--
        }
        var lineByte = line.toByteArray(charset(CHARSET))
        write(lineByte)
    }

    /**
     * 输出并换行
     */
    fun lineFeed() {
        write(printLineFeed())
    }

    /**
     *  @return 开启着重(设置文字加粗)
     */
    fun setEmphasizedOn() {
        write(emphasizedOn())
    }
    //

    /**
     *  @return 获取预打印数据 并关流
     */
    fun getDataAndClose(): ByteArray {
        bos.flush()
        var data = bos.toByteArray()
        bos.close()
        return data
    }

    /**
     * 设置文字大小(设置着重)
     * @param size 文字大小1-7 默认为0
     */
    fun setFontSize(size: Int) {
        write(fontSizeBig(size))
    }

    /**
     * 设置文字
     */
    fun printText(mssage: String) {
        var byteArrayMessage = mssage.toByteArray(charset(CHARSET))
        write(byteArrayMessage)
    }

    /**
     * 关闭着重
     */
    fun setEmphasizedOff() {
        write(emphasizedOff())
    }

    /**
     * 在一行打印
     */
    fun printInOneLine(name: String, answer: String, textSize: Int) {
        var lineLength = getLineStringWidth(textSize)
        var needEmpty = lineLength - (getStringWidth(name) + getStringWidth(answer)) % lineLength

        var empty:String =""
        while (needEmpty>0){
            empty += " "
            needEmpty --;
        }
        printText(name+empty+answer)

    }

    /**
     * 进纸切割
     */
    fun feedPaperCutPartial(){
        write(cutPape())
    }


    /**
     *  @return 画笔的处理
     */
    private fun initPrinter(): ByteArray {
        var result: ByteArray = ByteArray(2)
        result[0] = ESC
        result[1] = 64
        return result
    }

    private fun alignCenter(): ByteArray {
        var result = ByteArray(3)
        result[0] = ESC
        result[1] = 97
        result[2] = 1
        return result
    }

    private fun alignLeft(): ByteArray {
        var result = ByteArray(3)
        result[0] = ESC
        result[1] = 97
        result[2] = 0
        return result
    }

    fun getLineWidth(): Int {
        return 16
    }

    private fun printLineFeed(): ByteArray {
        var result = ByteArray(1)
        result[0] = LF
        return result
    }

    private fun emphasizedOn(): ByteArray {
        var result = ByteArray(3)
        result[0] = ESC
        result[1] = 69
        result[2] = 0xF
        return result
    }

    private fun fontSizeBig(num: Int): ByteArray {
        var realSize: Byte = 0
        when (num) {
            0 -> {
                realSize = 0
            }
            1 -> {
                realSize = 17
            }
            2 -> {
                realSize = 34
            }
            3 -> {
                realSize = 51
            }
            4 -> {
                realSize = 68
            }
            5 -> {
                realSize = 85
            }
            6 -> {
                realSize = 102
            }
            7 -> {
                realSize = 119
            }
        }
        var result = ByteArray(3)
        result[0] = GS
        result[1] = 33
        result[2] = realSize
        return result

    }

    private fun emphasizedOff(): ByteArray {
        var result = ByteArray(3)
        result[0] = ESC
        result[1] = 69
        result[2] = 0
        return result
    }

    //获取行宽
    private fun getLineStringWidth(textSize: Int): Int {
        return when (textSize) {
            0 -> 31
            1 -> 15
            else -> 31
        }
    }

    //获取文字宽度
    private fun getStringWidth(str: String): Int {
        var width = 0
        for (c in str.toCharArray()) {
            if (isChinese(c)) {
                width += 2
            } else {
                width += 1
            }
        }
        return width
    }

    /**
     * 判断是否中文
     * GENERAL_PUNCTUATION 判断中文的“号
     * CJK_SYMBOLS_AND_PUNCTUATION 判断中文的。号
     * HALFWIDTH_AND_FULLWIDTH_FORMS 判断中文的，号
     *
     * @param c 字符
     * @return 是否中文
     */
   private fun isChinese(c: Char): Boolean {
        val ub = Character.UnicodeBlock.of(c)
        return ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub === Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B || ub === Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub === Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS || ub === Character.UnicodeBlock.GENERAL_PUNCTUATION
    }
  private fun cutPape():ByteArray{
      var result =ByteArray(4)
      result[0]=GS
      result[1]=86
      result[2]=66
      result[3] =0
      return result

  }
}